Skip to content

Conversation

pamelafox
Copy link
Collaborator

@pamelafox pamelafox commented Aug 18, 2025

Purpose

Fix MSAL auth regression after the MSAL 4.x upgrade that caused "uninitialized_public_client_application" when MSAL APIs were called before initialization. This change:

  • Creates a stable PublicClientApplication instance and awaits initialize() before use
  • Adds exception handling and console logging to initialization
  • Adds a tiny loading placeholder during initialization so the app still renders

Fixes #2675.

Does this introduce a breaking change?

When developers merge from main and run the server, azd up, or azd deploy, will this produce an error?
If you're not sure, try it out on an old environment.

[ ] Yes
[x] No

Does this require changes to learn.microsoft.com docs?

This repository is referenced by this tutorial
which includes deployment, settings and usage instructions. If text or screenshot need to change in the tutorial,
check the box below and notify the tutorial author. A Microsoft employee can do this for you if you're an external contributor.

[ ] Yes
[x] No

Type of change

[x] Bugfix
[ ] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Documentation content changes
[ ] Other... Please describe:

Code quality checklist

See CONTRIBUTING.md for more details.

  • The current tests all pass (python -m pytest).
  • I added tests that prove my fix is effective or that my feature works
  • I ran python -m pytest --cov to verify 100% coverage of added lines
  • I ran python -m mypy to check for type errors
  • I either used the pre-commit hooks or ran ruff and black manually on my code.

…async init (fixes uninitialized_public_client_application); show small loading state
@pamelafox pamelafox requested a review from Copilot August 18, 2025 17:37
@pamelafox pamelafox changed the title Initialize MSAL before use to fix auth regression (fixes #2675) Initialize MSAL before use to fix auth regression Aug 18, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an MSAL authentication regression that occurred after upgrading to MSAL 4.x, where calling MSAL APIs before initialization caused "uninitialized_public_client_application" errors. The fix ensures proper MSAL initialization with error handling and provides a loading state during initialization.

  • Creates a stable PublicClientApplication instance using useMemo to prevent re-initialization
  • Adds proper async initialization with await on initialize() before using MSAL APIs
  • Implements error handling, console logging, and a loading placeholder during initialization

if (useLogin) {
var msalInstance = new PublicClientApplication(msalConfig);
// Create a stable MSAL instance (avoid re-init/duplicate listeners; single shared client for MsalProvider).
const msalInstance = useMemo(() => new PublicClientApplication(msalConfig), []);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cline's suggested fix did not use useMemo, but Copilot+GPT5 thought it was a good idea, to avoid re-construction across renders.

Copy link

@DanWahlin DanWahlin Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs show this general type of pattern for accomplishing that (without useMemo()), but useMemo() should achieve the goal of ensuring it's only created once. I don't know enough about the app to understand the overall flow and how often the component is rerendered. But, assuming it is, useMemo should help there.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an SPA - my understanding is that this wrapper holds all the content displayed and shouldn't be re-rendered unless the page is refreshed

const msalInstance = useMemo(() => new PublicClientApplication(msalConfig), []);
const [initialized, setInitialized] = useState(false);
// Track mount state so we don't call setState after unmount if async init resolves late
const mounted = useRef<boolean>(true);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new mounted ref is to avoid setState calls inside the async init() below if the component unmounts during all that. Don't know how common that is.

Copy link
Collaborator

@mattgotteiner mattgotteiner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Recommend switching to singleton pattern to make it easier

https://learn.microsoft.com/en-us/entra/msal/javascript/react/getting-started#initialization

Combined with something like this

// main bootstrap (index.tsx or similar)
import { createRoot } from "react-dom/client";
import { MsalProvider } from "@azure/msal-react";
import { msalInstance } from "./auth/msal";
import App from "./App";

(async () => {
await msalInstance.initialize(); // ensures MSAL is ready before any API use
createRoot(document.getElementById("root")!).render(



);
})();

@pamelafox
Copy link
Collaborator Author

@DanWahlin @mattgotteiner I've revised the PR to use an approach closer to the documentation, with the MsalProvider moved into index.tsx, and then Layout uses useMsal.

@pamelafox pamelafox marked this pull request as ready for review August 20, 2025 17:10
@DanWahlin
Copy link

I like that approach better. Eliminates any rerenders which would get rid of the singleton challenge.

@pamelafox pamelafox merged commit 84cf73e into Azure-Samples:main Aug 21, 2025
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Broken Authentication Due to MSAL Library Upgrade
3 participants